El dataset seleccionado es master_dataset.csv.
link: https://www.covid19survivalcalculator.com/download
Licencia: Este conjunto de datos se encuentra bajo el "Attribution 4.0 International (CC BY 4.0)" licencia. Usted es libre de usarlo para uso personal, educativo, de investigación y comercial siempre que atribuya el conjunto de datos a "Nexoid" Para más información visite Attribution 4.0 International (CC BY 4.0).
Para cargar el dataset, debido al excesivo ruido, se optó por elegir los valores que se considerarían como nulos o vacíos al momento de cargar el Dataset.
# Cargar los datasets.
%matplotlib notebook
import pandas as pd
import numpy as np
_PATH = '4.DatasetsCOVID19/'
file = 'master_dataset.csv'
dataset = _PATH + file
df = pd.read_csv(dataset, ',', dtype='str',
keep_default_na=False, na_values=['na', '', 'null', 'NaN', 'undefined'])
df
# Funciones que nos ayudarán en la verificación del ruido
def printNaN(df):
columns_with_null = df.columns[df.isnull().any()]
if len(columns_with_null) > 0:
for c in columns_with_null:
print(c, ': ', df[c].isnull().sum())
else:
print('None')
def printType(df):
columns = df.columns
dataTypeSeries = df.dtypes
i = 0
for c in columns:
print(c, ": ", dataTypeSeries[i])
i+=1
printNaN(df)
#print('\n\n')
#printType(df)
df_p = df
# 1. Eliminar filas que presentan mucho ruido al igual que la fecha.
df_p = df_p.iloc[:, range(1, len(df_p.columns) - 1)]
df_p.drop([211409, 211676, 352078, 539050, 544425], axis=0,inplace=True)
df_p
# PREPROCESADO: Reemplazar los valores NULL o NaN
# 1 UK = Unknow
df_p['region'].fillna('UK', inplace=True)
df_p['country'].fillna('UK', inplace=True)
df_p['working'].fillna('unknow', inplace=True)
df_p['blood_type'].fillna('unknow', inplace=True)
df_p['sex'].fillna('unknow', inplace=True)
# 2 Cambiar por 0
df_p['contacts_count'].fillna(0, inplace=True)
df_p['house_count'].fillna(0, inplace=True)
df_p['ip_accuracy'].fillna(0, inplace=True)
df_p['public_transport_count'].fillna(0, inplace=True)
df_p['worried'].fillna(0, inplace=True)
df_p['rate_reducing_mask'].fillna(0, inplace=True)
df_p['rate_reducing_mask_type'].fillna(0, inplace=True)
df_p['opinion_infection'].fillna(0, inplace=True)
df_p['opinion_mortality'].fillna(0, inplace=True)
# 3 "blank"
df_p['insurance'].fillna('blank', inplace=True)
df_p['income'].fillna('blank', inplace=True)
df_p['immigrant'].fillna('blank', inplace=True)
# 4 "other"
df_p['race'].fillna('other', inplace=True)
# 5 "never"
df_p['smoking'].fillna('never', inplace=True)
# 6 Cambiar por -1
df_p['alcohol'].fillna(-1, inplace=True)
# 7 Cambiar por -2
df_p['cannabis'].fillna(-2, inplace=True)
df_p['amphetamines'].fillna(-2, inplace=True)
df_p['cocaine'].fillna(-2, inplace=True)
df_p['lsd'].fillna(-2, inplace=True)
df_p['mdma'].fillna(-2, inplace=True)
# 8 Cambiar por "none"
df_p['prescription_medication'].fillna('none', inplace=True)
# 9 Cambiar por 20_30
df_p['age'].fillna('20_30', inplace=True)
# PREPROCESADO: Transformar variables CATEGORICAS y NUMERICAS
# 1. Categoricas Ordinales
# Para evitar errores en el dataset: De que hay valores nulos.
df_p['region'].replace('NA', 'AN', inplace=True)
df_p['country'].replace('NA', 'AN', inplace=True)
# 2 Variable income: porque si importa el orden de ingresos
df_p['income'].replace('blank', 0, inplace=True)
df_p['income'].replace('gov', 1, inplace=True)
df_p['income'].replace('low', 2, inplace=True)
df_p['income'].replace('med', 3, inplace=True)
df_p['income'].replace('high', 4, inplace=True)
# 3 Variable rate_reducing_mask_type: porque si importa el nivel de proteccion
df_p['rate_reducing_mask_type'].replace('clothhome', 1, inplace=True)
df_p['rate_reducing_mask_type'].replace('clothstore', 2, inplace=True)
df_p['rate_reducing_mask_type'].replace('surgical', 3, inplace=True)
df_p['rate_reducing_mask_type'].replace('level1', 4, inplace=True)
df_p['rate_reducing_mask_type'].replace('level2', 5, inplace=True)
df_p['rate_reducing_mask_type'].replace('level3', 6, inplace=True)
# 4 Introducir valores NaN con su media
risk_infection_mean = pd.to_numeric(df_p['risk_infection'], errors='coerce').mean()
risk_mortality_mean = pd.to_numeric(df_p['risk_mortality'], errors='coerce').mean()
bmi_mean = pd.to_numeric(df_p['bmi'], errors='coerce').mean()
height_mean = pd.to_numeric(df_p['height'], errors='coerce').mean()
weight_mean = pd.to_numeric(df_p['weight'], errors='coerce').mean()
df_p['risk_infection'].fillna(float(risk_infection_mean), inplace=True)
df_p['risk_mortality'].fillna(float(risk_mortality_mean), inplace=True)
df_p['bmi'].fillna(float(bmi_mean), inplace=True)
df_p['height'].fillna(float(height_mean), inplace=True)
df_p['weight'].fillna(float(weight_mean), inplace=True)
df_p.reset_index(drop=True, inplace=True)
n = len(df_p['prescription_medication'])
# 5 Variable prescription_medication; debido a la cantidad de datos,
# se opto por tomarle como si fuera una categorica ordinal, en donde importa
# la cantidad de medicamentos prescritos
for i in range(n):
s = str(df_p.at[i, 'prescription_medication']).split(';')
if (s[0] == "none"):
df_p.at[i, 'prescription_medication'] = 0
else:
df_p.at[i, 'prescription_medication'] = len(s)
# Creación y almacenamiento del Dataset limpio y listo para procesar.
DatasetPreprocesado = pd.DataFrame(data=df_p,columns=df_p.columns)
DatasetPreprocesado.to_csv("recursos/Nexoid-Limpio.csv", sep=";", index = False)
DatasetPreprocesado
# Cargar el dataset limpio.
import pandas as pd
import numpy as np
#Se carga el DataSet, sin ruido y dtype apropiados.
df_limpio = pd.read_csv("recursos/Nexoid-Limpio.csv", ';', low_memory=False)
printNaN(df_limpio)
df_limpio
from sklearn.model_selection import train_test_split
# Se seleccionan los datos con un rango de edad de 80 a 100
df_d = df_limpio[(((df_limpio['age'] == '60_70') | (df_limpio['age'] == '70_80')
| (df_limpio['age'] == '80_90') | (df_limpio['age'] == '90_100')))]
df_d.reset_index(inplace=True)
df_d = df_d.drop('index', 1)
df_d.to_csv("recursos/N-Filtrado-Edades.csv", sep=";", index = False)
df_e = df_d[(df_d['covid19_positive'] == 0)]
print(len(df_e.values))
df_e, df_e_test = train_test_split(df_e, test_size=0.00436, random_state=0)
df_f = df_d[(df_d['covid19_positive'] == 1)]
df_d = pd.concat([df_f, df_e_test])
df_d.sort_index(inplace=True)
df_d.reset_index(inplace=True)
df_d = df_d.drop('index', 1)
df_d
Cabe recalcar que, en este punto, se realizó primero los siguientes procesos con el Dataset Limpio completo; posteriormente, este se almacenó como DatasetPreprocesado.csv, sin ser filtrado por el rango de edades, esto con el fin de realizar el análisis.
# Estas variables representan a las traducciones de los atributos originales
encoderNames_esp = ['region', 'pais', 'sexo', 'edad', 'tipo_sangre', 'seguro', 'etnia', 'inmigrante', 'fumando', 'trabajando']
otherNames_esp = ['ip_latitud', 'ip_longitud', 'ip_precision','altura', 'peso', 'imc', 'ingresos',
'alcohol', 'canabis', 'anfetaminas', 'cocaina', 'lsd', 'mdma', 'numero_contactos',
'numero_conviviente', 'numero_transporte_publico', 'preocupado', 'tasa_reduccion_riesgo_personal',
'tasa_reduccion_riesgo_personal_distanciamiento_social', 'tasa_reduccion_riesgo_personal_lavado_manos',
'tasa_reduccion_riesgo_hogar', 'tasa_reducción_riesgo_hogar_distanciamiento_social',
'tasa_reduccion_riesgo_lavado_manos_hogar', 'tasa_reduccion_riesgo_desinfectante',
'tasa_reduccion_mascarilla', 'tasa_reduccion_tipo_mascarilla', 'tasa_ayuda_gubernamental',
'tasa_control_gubernamental', 'tasa_gasto_gubernamental', 'covid19_positivo',
'sintomas_covid19', 'contacto_covid19', 'asma', 'enfemedad_riniones', 'enfemedad_higado',
'inmunidad_comprometida', 'enfermedad_corazon', 'enfermedad_pulmonar', 'diabetes', 'vih_positivo',
'hipertension', 'otras_enfermedades_cronicas', 'asilo', 'trabajador_sanitario', 'prescripcion_medica',
'opinion_infeccion', 'opinion_mortalidad', 'riesgo_infeccion', 'riesgo_mortalidad']
atributos = ['region', 'pais', 'ip_latitud', 'ip_longitud', 'ip_precision', 'sexo', 'edad', 'altura', 'peso', 'imc',
'tipo_sangre', 'seguro', 'ingresos', 'etnia', 'inmigrante', 'fumando',
'alcohol', 'canabis', 'anfetaminas', 'cocaina', 'lsd', 'mdma', 'numero_contactos',
'numero_conviviente', 'numero_transporte_publico', 'trabajando', 'preocupado', 'tasa_reduccion_riesgo_personal',
'tasa_reduccion_riesgo_personal_distanciamiento_social', 'tasa_reduccion_riesgo_personal_lavado_manos',
'tasa_reduccion_riesgo_hogar', 'tasa_reducción_riesgo_hogar_distanciamiento_social',
'tasa_reduccion_riesgo_lavado_manos_hogar', 'tasa_reduccion_riesgo_desinfectante',
'tasa_reduccion_mascarilla', 'tasa_reduccion_tipo_mascarilla', 'tasa_ayuda_gubernamental',
'tasa_control_gubernamental', 'tasa_gasto_gubernamental', 'covid19_positivo',
'sintomas_covid19', 'contacto_covid19', 'asma', 'enfemedad_riniones', 'enfemedad_higado',
'inmunidad_comprometida', 'enfermedad_corazon', 'enfermedad_pulmonar', 'diabetes', 'vih_positivo',
'hipertension', 'otras_enfermedades_cronicas', 'asilo', 'trabajador_sanitario', 'prescripcion_medica',
'opinion_infeccion', 'opinion_mortalidad', 'riesgo_infeccion', 'riesgo_mortalidad']
df_d.columns = atributos
df_d
from sklearn.preprocessing import OneHotEncoder, StandardScaler, MinMaxScaler
from sklearn.compose import make_column_transformer, ColumnTransformer
from sklearn.pipeline import Pipeline
# Descomentar para Transformar los otros datasets.
# df_d = pd.read_csv("recursos/N-Filtrado-Edades.csv", ';', low_memory=False)
# df_d = pd.read_csv("recursos/Nexoid-Limpio.csv", ';', low_memory=False)
# Se realiza un preprocesamiento de las variables NUMÉRICAS usando StandardScaler.
# Se realiza un preprocesamiento de las variables CATEGÓRICAS NOMINALES usando OneHotEncoder.
# Array que contiene las columnas que son CATEGóRICAS NOMINALES, según el dataset.
encoderNames = ['region', 'country', 'sex', 'age', 'blood_type', 'insurance', 'race', 'immigrant', 'smoking', 'working']
otherNames = ['ip_latitude', 'ip_longitude', 'ip_accuracy','height', 'weight', 'bmi', 'income',
'alcohol', 'cannabis', 'amphetamines', 'cocaine', 'lsd', 'mdma', 'contacts_count',
'house_count', 'public_transport_count', 'worried', 'rate_reducing_risk_single',
'rate_reducing_risk_single_social_distancing', 'rate_reducing_risk_single_washing_hands',
'rate_reducing_risk_house', 'rate_reducing_risk_house_social_distancing',
'rate_reducing_risk_house_washing_hands', 'rate_reducing_risk_single_sanitizer',
'rate_reducing_mask', 'rate_reducing_mask_type', 'rate_government_action',
'rate_government_control', 'rate_government_spend', 'covid19_positive',
'covid19_symptoms', 'covid19_contact', 'asthma', 'kidney_disease', 'liver_disease',
'compromised_immune', 'heart_disease', 'lung_disease', 'diabetes', 'hiv_positive',
'hypertension', 'other_chronic', 'nursing_home', 'health_worker', 'prescription_medication',
'opinion_infection', 'opinion_mortality', 'risk_infection', 'risk_mortality']
# Estableces las variables traducidas
encoderNames = encoderNames_esp
otherNames = otherNames_esp
# Aplicación del método OneHotEncoder(Coding) para transformar los datos.
preprocesador1 = make_column_transformer((OneHotEncoder(), encoderNames), remainder='passthrough')
X = preprocesador1.fit_transform(df_d)
pre_features = preprocesador1.transformers_[0][1].get_feature_names(encoderNames)
pre_features = pre_features.tolist()
pre_features.extend(otherNames)
# Usar X.todense() al problema de Dimensiones.
categorical = pd.DataFrame(data=X, columns=pre_features)
escalerNames = []
salida = 'covid19_positivo'
for col in categorical.columns:
if(col != salida):
escalerNames.append(col)
preprocesador2 = make_column_transformer((MinMaxScaler(), escalerNames), remainder='passthrough')
procesado = preprocesador2.fit_transform(categorical)
escalerNames.append(salida);
print(len(escalerNames))
Data = pd.DataFrame(data=procesado,columns=escalerNames)
# Descomentar para guardar los otros datasets.
#Data.to_csv("recursos/Nexoid.csv", sep=";",index = False)
#Data.to_csv("recursos/N-Filtrado.csv", sep=";",index = False)
Data.to_csv("recursos/N-Equilibrado.csv", sep=";",index = False)
Data
import pandas as pd
import numpy as np
df_a = pd.read_csv("recursos/Nexoid.csv", ';')
df_a
des = df_a.describe()
des
var = df_a.var()
#i = 0
#for v in var.index:
# print(v, ":", var[i])
# i += 1
var
# Correlación de todas las variables
correlacion = df_a.corr()
# Debido a que es imposible tener una buena perspectiva visual con el
# mapa de calor, se optó por buscar e imprimir los valores más altos.
correlacion
print("------ Los atributos con correlación positiva ------\n")
print("\t\t RISK_INFECTION\n")
print(correlacion['risk_infection'].nlargest(10))
print("\n\t\t RISK_MORTALITY\n")
print(correlacion['risk_mortality'].nlargest(10))
print("\n\t\t COVID19_POSITIVE\n")
print(correlacion['covid19_positive'].nlargest(20))
print("\n------ Los atributos con correlación negativa ------\n")
print("\t\t RISK_INFECTION\n")
print(correlacion['risk_infection'].nsmallest(9))
print("\n\t\t RISK_MORTALITY\n")
print(correlacion['risk_mortality'].nsmallest(9))
print("\n\t\t COVID19_POSITIVE\n")
print(correlacion['covid19_positive'].nsmallest(19))
Al realizar la estadística descriptiva, observamos que la correlación respecto al covid19_positive, tiene una correlación positiva con las edades avanzadas, por lo que se optó por realizar el filtrado explicado anterior, y a partir de este dataset, realizar los siguientes procedimientos.
%matplotlib notebook
import pandas as pd
import numpy as np
df_b = pd.read_csv("recursos/N-Equilibrado.csv", ';')
df_b
df_b_corr = df_b.corr()
print("------ Los atributos con correlación positiva ------\n")
print("\t\t RISK_INFECTION\n")
print(df_b_corr['riesgo_infeccion'].nlargest(20))
print("\n\t\t RISK_MORTALITY\n")
print(df_b_corr['riesgo_mortalidad'].nlargest(20))
print("\n\t\t covid19_positive\n")
print(df_b_corr['covid19_positivo'].nlargest(20))
print("\n------ Los atributos con correlación negativa ------\n")
print("\t\t RISK_INFECTION\n")
print(df_b_corr['riesgo_infeccion'].nsmallest(19))
print("\n\t\t RISK_MORTALITY\n")
print(df_b_corr['riesgo_mortalidad'].nsmallest(19))
print("\n\t\t covid19_positive\n")
print(df_b_corr['covid19_positivo'].nsmallest(19))
Nota: Se realizaron las correlaciones para verificar que los datos no se alteren y mantengan el análisis previo.
Extra: Visualización de la cantidad de datos de los datasets procesados y el original.
df_completo = pd.read_csv("recursos/Nexoid-Limpio.csv", ';', low_memory=False)
df_f_edades = pd.read_csv("recursos/N-Filtrado.csv", ';', low_memory=False)
df_f = pd.read_csv("recursos/N-Equilibrado.csv", ';', low_memory=False)
len_limpio = df_completo.groupby(df_completo['covid19_positive'])['covid19_positive'].count()
print('Nexoid Total:', df_completo['covid19_positive'].count(), '\n\t', len_limpio)
len_f_edades = df_f_edades.groupby(df_f_edades['covid19_positive'])['covid19_positive'].count()
print('\nN-Filtrado Total:', df_f_edades['covid19_positive'].count(), '\n\t', len_f_edades)
len_f = df_f.groupby(df_f['covid19_positivo'])['covid19_positivo'].count()
print('\nN-Equilibrado Total:', df_f['covid19_positivo'].count(), '\n\t', len_f)
# Función para descubrir el mejor K, basado en porcentajes
# respecto al valor anterior. Metodo Elbow
def descubrirXElbow(y, x_min=1, porcentaje=0.8):
y_len = len(y)
aux = y[0]
i = 1
p_aux = 0
optimized_x = x_min
while(i < y_len):
p = round((y[i] / aux), 4)
if p_aux != 0:
if p >= porcentaje:
optimized_x -= 1
i = y_len
else:
p_aux = 0
elif p >= porcentaje and p <= 1:
p_aux = p
if i < y_len:
aux = y[i]
optimized_x += 1
i += 1
return optimized_x
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
#df_edades = pd.read_csv("recursos/DatasetEdadesPreprocesado.csv", ';', low_memory=False)
# Se carga el archivo CSV con los datos preprocesados que creó anteriormente.
df_Preprocesado = df_b
# Cálculo PCA sin componentes.
componentesPrincipales = PCA().fit(df_Preprocesado)
varianza = componentesPrincipales.explained_variance_ratio_
num_CP= range(1, len(varianza) + 1)
# Gráfica de las muestra en 2D.
fig1 = plt.figure('Análisis mediante el gráfico del codo')
fig1.subplots_adjust(hspace=0.6, wspace=0.5)
ax = fig1.add_subplot(2, 1, 1)
ax.plot(num_CP, varianza, color='black', linestyle='dashed', linewidth = 3,
marker='o', markerfacecolor='blue', markersize=11)
#ax.set_title('Análisis mediante el Método del Codo')
ax.set_xlabel('Número de Componentes Principales')
ax.set_ylabel('Varianza')
ax.grid(True)
num_CP= range(1, 11)
ax = fig1.add_subplot(2, 1, 2)
ax.plot(num_CP, varianza[:10:], color='black', linestyle='dashed', linewidth = 3,
marker='o', markerfacecolor='red', markersize=11)
#ax.set_title('Análisis mediante el Método del Codo con acercamiento')
ax.set_xlabel('Número de Componentes Principales')
ax.set_ylabel('Varianza')
ax.grid(True)
plt.savefig('recursos/graficas/pcaCodo.png', dpi=300)
plt.show()
# El mejor componente para realizar reducción de dimensionalidad.
componentes = descubrirXElbow(varianza)
print("La mejor cantidad de componentes principales:", componentes)
Variables que más se relaciones en cada componente del PCA.
salida_completo = df_b['covid19_positivo']
df_completo = df_b.drop('covid19_positivo', axis=1)
col_pca = []
for i in range(1, componentes + 1):
col = "PC" + str(i)
col_pca.append(col)
pca = PCA(componentes)
df_completo_pca = pca.fit_transform(df_completo)
df_completo_pca = pd.DataFrame(df_completo_pca, columns=col_pca)
com = pd.DataFrame(data=pca.components_, columns=df_completo.columns, index = col_pca)
for idx in com.index:
print(str(idx) + ':\n', round(com.loc[str(idx)].nlargest(10), 3), '\n')
print("Correlaciónes Componentes-Salida:")
df_completo_pca.corrwith(salida_completo)
# SPLITTING DATASET - 80 para Train y 20 para Test
from sklearn.model_selection import train_test_split
X = df_b.drop('covid19_positivo', 1)
y = df_b['covid19_positivo']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
#print(X_train.shape)
#print(X_test.shape)
#print(y_train.shape)
#print(y_test.shape)
#print(X_test)
print("Tamaño X_test: ", len(X_test.values))
X_train
Cálculo del Accuracy.
from sklearn.preprocessing import StandardScaler, MinMaxScaler, normalize
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
import time
import datetime
x = range(1, min(X_train.shape) + 1)
listaAccuaracy = []
tiempos = []
tiempo_inicial = time.time()
for (comp) in x:
tiempo_inicial_random = time.time()
# Aplicamos PCA.
pca = PCA(n_components=comp)
X_train_PCA = pca.fit_transform(X_train)
X_test_PCA = pca.transform(X_test)
explained_variance = pca.explained_variance_ratio_
# Se realiza de nuevo el entrenamiento con Random Forest.
clasificador = RandomForestClassifier(max_depth=15, random_state=0)
clasificador.fit(X_train_PCA, y_train)
# Se realiza una nueva predicción en base al Test.
y_pred = clasificador.predict(X_test_PCA)
# Finalmente se evalúan los resultados.
cm = confusion_matrix(y_test, y_pred)
listaAccuaracy.append(round(accuracy_score(y_test, y_pred,
normalize=True), 5))
tiempo_final_random = time.time()
tiempos.append(tiempo_final_random - tiempo_inicial_random)
listaAccuaracy = np.array(listaAccuaracy)
print('Accuracy, '+str(componentes) + ' Componentes principales\n',
listaAccuaracy[componentes -1:componentes])
maximo = np.amax(listaAccuaracy)
posicion = np.where(listaAccuaracy == np.amax(listaAccuaracy))
print('\nNúmero de componentes: ' + str((posicion[0]+1)))
print('\nMejor Accuracy: ' + str(maximo))
tiempo_final = time.time()
tiempo_ejecucion = (tiempo_final - tiempo_inicial)
print('\nTiempo de ejecución total: ',
datetime.timedelta(seconds=tiempo_ejecucion))
# Imprimir arbol en una imágen png
from sklearn.tree import export_graphviz
from sklearn.tree import export_graphviz
import pydot
tree = clasificador.estimators_[50]
export_graphviz(tree, out_file = 'recursos/tree.dot',
feature_names = X_train.columns, rounded = True, precision = 1)
(graph, ) = pydot.graph_from_dot_file('recursos/tree.dot')
graph.write_png('recursos/tree.png')
Visualización del tiempo de ejecución y Accuracy
fig6 = plt.figure('Modelo orientado a clasificación (random forest)')
fig6.subplots_adjust(hspace=0.6, wspace=0.5)
ax = fig6.add_subplot(1, 1, 1)
ax.plot(x[:30:], tiempos[:30:], color='black', linestyle='dashed', linewidth = 1,
marker='o', markerfacecolor='red', markersize=5)
#ax.set_title('Tiempo en base al número de componentes')
ax.set_xlabel('Número Componentes Principales')
ax.set_ylabel('Tiempo en segundos')
ax.grid(True)
plt.savefig('recursos/graficas/tiempo_random-forest.png', dpi=300)
plt.show()
fig8 = plt.figure('Gráfica Accuracy')
fig8.subplots_adjust(hspace=0.6, wspace=0.5)
ax = fig8.add_subplot(1, 1, 1)
ax.plot(x[:30:], listaAccuaracy[:30:], color='black', linestyle='dashed', linewidth = 3,
marker='o', markerfacecolor='green', markersize=11)
#ax.set_title('Accuracy en base al número de componentes')
ax.set_xlabel('Número Componentes Principales')
ax.set_ylabel('Accuracy')
ax.grid(True)
plt.savefig('recursos/graficas/accuracy-plot.png', dpi=300)
plt.show()
from sklearn.tree import export_graphviz
from sklearn.tree import export_graphviz
import pydot
# SPLITTING DATASET
from sklearn.model_selection import train_test_split
X = df_completo_pca
y = salida_completo
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
x = range(1, min(X_train.shape) + 1)
clasificador = RandomForestClassifier(max_depth=15, random_state=0)
clasificador.fit(X_train, y_train)
y_pred = clasificador.predict(X_test)
accuaracy = (round(accuracy_score(y_test, y_pred, normalize=True), 2))
print('Accuracy:', accuaracy)
# Imprimir arbol en una imágen png
tree = clasificador.estimators_[0]
export_graphviz(tree, out_file = 'recursos/tree.dot',
feature_names = X_train.columns, rounded = True, precision = 1)
(graph, ) = pydot.graph_from_dot_file('recursos/tree.dot')
graph.write_png('recursos/tree.png')
from sklearn.decomposition import PCA
from scipy.spatial.distance import cdist
from sklearn.cluster import KMeans
import datetime
import time
from sklearn.utils.testing import ignore_warnings
from sklearn.exceptions import ConvergenceWarning
@ignore_warnings(category=ConvergenceWarning)
# Función para obtener las distorisiones
def getDistortions(X, k_max):
K_range=range(2, k_max + 1, 1)
distortions=[]
KMeanTime = []
for i in K_range:
tiempo_inicial = time.time()
kmeanModel = KMeans(n_clusters=i)
kmeanModel.fit(X)
r = kmeanModel.inertia_
distortions.append(round(r, 4))
tiempo_final = time.time()
KMeanTime.append((tiempo_final - tiempo_inicial))
return distortions, KMeanTime
# Función para realizar el Clustering
def doKmeans(X, nclust=2, init='k-means++', max_iter=100,
tol=0.0001, random_state=0, algorithm='full'):
model = KMeans(nclust, init=init, random_state=random_state)
model.fit(X)
clust_labels = model.predict(X)
cent = model.cluster_centers_
return (clust_labels, cent)
Cálculo y visualización del Clustering
%matplotlib notebook
import matplotlib.pyplot as plt
k_max = min(df_b.shape)
df_s = df_completo_pca.values
tiempo_inicial = time.time()
distorsiones, distorsionesTime = getDistortions(df_s, k_max)
tiempo_final = time.time()
tiempo_ejecucion = (tiempo_final - tiempo_inicial)
df_s = pd.DataFrame(data=df_s)
print('Tiempo de ejecución total: ', datetime.timedelta(seconds=tiempo_ejecucion))
K_range = np.arange(2, k_max + 1)
fig3=plt.figure('Distorsión-Media')
fig3.subplots_adjust(hspace=0.6, wspace=0.5)
ex = fig3.add_subplot(2,1,1)
ex.plot(K_range, distorsiones[:k_max - 1:1], 'b*-')
ex.grid(True)
ex.set_xlabel('Número de Clústers')
ex.set_ylabel('Media de distorsión')
#ex.set_title('Distorsión Media - Método Elbow')
K_range = K_range[:25:]
ex = fig3.add_subplot(2,1,2)
ex.plot(K_range, distorsiones[:25:], 'r*-')
ex.grid(True)
ex.set_xlabel('Número de Clústers')
ex.set_ylabel('Media de distorsión')
#ex.set_title('Distorsión Media - Método Elbow con acercamiento')
plt.savefig('recursos/graficas/distorsion-media.png', dpi=300)
plt.show()
K = descubrirXElbow(distorsiones, x_min=2, porcentaje=0.81)
print('\nEl mejor K: ', K)
Agrupamiento del dataset filtrado por edades.
clust_labels, cent = doKmeans(df_completo_pca, K, 'k-means++', random_state=0)
kmeans_pca = pd.DataFrame(clust_labels, columns=['Grupos'])
print('Grupos con ', K, ' Clusters.\n')
kmeans_pca
Visualización de los Grupos calculados.
import random
# Realizar estadística descriptiva de cada cluster
df_cluster = pd.concat([df_b, kmeans_pca], axis=1)
UserGrupoK_pca=kmeans_pca.groupby(kmeans_pca.Grupos).Grupos.count()
UserGrupoK_pca=UserGrupoK_pca.sort_values(ascending=False, inplace=False, kind='quicksort')
print(UserGrupoK_pca)
x_range = UserGrupoK_pca.index
number_of_colors = len(x_range)
colors = ["#"+''.join([random.choice('0123456789ABCDEF') for j in range(6)])
for i in range(number_of_colors)]
fig20 = plt.figure('Cantidad de muestras por Cluster')
ex = fig20.add_subplot(1,1,1)
ex.bar(x_range, UserGrupoK_pca)
ex.grid(True)
ex.set_ylabel('Cantidad de personas')
ex.set_xlabel('Número de Clusters')
#ex.set_title('Cantidad de personas por Cluster')
plt.savefig('recursos/graficas/persona-cluster.png', dpi=300)
plt.show()
Correlaciones con los grupos más relevantes.
df_cluster_1 = df_cluster[(((df_cluster['Grupos'] == 1)))]
des_1 = df_cluster_1.describe()
var = df_cluster_1.var()
print('Media:\n\n', des_1.loc['mean'].nlargest(15))
print('\nDesviación Típica:\n\n', des_1.loc['std'].nlargest(15))
print('\nVarianza:\n\n', var.where(var != 0.0).nsmallest(15))
cov_positivo = df_cluster_1#[(df_cluster_1['covid19_positive'] == 1.0)]
correlacion_c1 = cov_positivo.corr()
print("\n------ Los atributos con correlación positiva ------\n")
print(correlacion_c1['covid19_positivo'].nlargest(20))
print("\n------ Los atributos con correlación negativa ------\n")
print(correlacion_c1['covid19_positivo'].nsmallest(19))
df_cluster_2 = df_cluster[(((df_cluster['Grupos'] == 2)))]
des_2 = df_cluster_2.describe()
print('Media:\n\n', des_2.loc['mean'].nlargest(15))
print('\nDesviación Típica:\n\n', des_2.loc['std'].nlargest(15))
print('\nVarianza:\n\n', df_cluster_2.var().nlargest(15))
correlacion_c2 = df_cluster_2.corr()
print("\n------ Los atributos con correlación positiva ------\n")
print(correlacion_c2['covid19_positivo'].nlargest(20))
print("\n------ Los atributos con correlación negativa ------\n")
print(correlacion_c2['covid19_positivo'].nsmallest(19))
df_cluster_4 = df_cluster[(((df_cluster['Grupos'] == 4)))]
des_4 = df_cluster_4.describe()
print('Media:\n\n', des_4.loc['mean'].nlargest(15))
print('\nDesviación Típica:\n\n', des_4.loc['std'].nlargest(15))
print('\nVarianza:\n\n', df_cluster_4.var().nlargest(15))
correlacion_c4 = df_cluster_4.corr()
print("\n------ Los atributos con correlación positiva ------\n")
print(correlacion_c4['covid19_positivo'].nlargest(20))
print("\n------ Los atributos con correlación negativa ------\n")
print(correlacion_c4['covid19_positivo'].nsmallest(19))
df_cluster_0 = df_cluster[(((df_cluster['Grupos'] == 0)))]
des_0 = df_cluster_0.describe()
print('Media:\n\n', des_0.loc['mean'].nlargest(15))
print('\nDesviación Típica:\n\n', des_0.loc['std'].nlargest(15))
print('\nVarianza:\n\n', df_cluster_0.var().nlargest(15))
correlacion_c0 = df_cluster_0.corr()
print("\n------ Los atributos con correlación positiva ------\n")
print(correlacion_c0['covid19_positivo'].nlargest(20))
print("\n", correlacion_c0['riesgo_mortalidad'].nlargest(20))
print("\n------ Los atributos con correlación negativa ------\n")
print(correlacion_c0['covid19_positivo'].nsmallest(19))
salida_cluster_1 = df_cluster_1['covid19_positivo']
df_cluster_1_tmp = df_cluster_1.drop('covid19_positivo', axis=1)
df_cluster_1_tmp = df_cluster_1_tmp.drop('Grupos', axis=1)
pca = PCA(3)
df_cluster_1_pca = pca.fit_transform(df_cluster_1_tmp)
df_cluster_1_pca = pd.DataFrame(df_cluster_1_pca, columns = ['PC1', 'PC2', 'PC3'])
com = pd.DataFrame(data=pca.components_, columns=df_cluster_1_tmp.columns, index = ['PC1', 'PC2', 'PC3'])
print('PC1:\n', round(com.loc['PC1'].nlargest(10), 3))
print('\nPC2:\n', round(com.loc['PC2'].nlargest(10), 3))
print('\nPC3:\n', round(com.loc['PC3'].nlargest(10), 3))
df_cluster_1_pca.corrwith(salida_cluster_1)
salida_cluster_2 = df_cluster_2['covid19_positivo']
df_cluster_2_tmp = df_cluster_2.drop('covid19_positivo', axis=1)
df_cluster_2_tmp = df_cluster_2_tmp.drop('Grupos', axis=1)
pca = PCA(componentes)
df_cluster_2_pca = pca.fit_transform(df_cluster_2_tmp)
df_cluster_2_pca = pd.DataFrame(df_cluster_2_pca, columns=['PC1', 'PC2', 'PC3'])
com = pd.DataFrame(data=pca.components_, columns=df_cluster_2_tmp.columns, index = ['PC1', 'PC2', 'PC3'])
print('PC1:\n', round(com.loc['PC1'].nlargest(10), 3))
print('\nPC2:\n', round(com.loc['PC2'].nlargest(10), 3))
print('\nPC3:\n', round(com.loc['PC3'].nlargest(10), 3))
df_cluster_2_pca.corrwith(salida_cluster_2)
salida_cluster_4 = df_cluster_4['covid19_positivo']
df_cluster_4_tmp = df_cluster_4.drop('covid19_positivo', axis=1)
df_cluster_4_tmp = df_cluster_4_tmp.drop('Grupos', axis=1)
pca = PCA(componentes)
df_cluster_4_pca = pca.fit_transform(df_cluster_4_tmp)
df_cluster_4_pca = pd.DataFrame(df_cluster_4_pca, columns=['PC1', 'PC2', 'PC3'])
com = pd.DataFrame(data=pca.components_, columns=df_cluster_4_tmp.columns, index = ['PC1', 'PC2', 'PC3'])
print('PC1:\n', round(com.loc['PC1'].nlargest(10), 3))
print('\nPC2:\n', round(com.loc['PC2'].nlargest(10), 3))
print('\nPC3:\n', round(com.loc['PC3'].nlargest(10), 3))
df_cluster_4_pca.corrwith(salida_cluster_4)
salida_cluster_0 = df_cluster_0['covid19_positivo']
df_cluster_0_tmp = df_cluster_0.drop('covid19_positivo', axis=1)
df_cluster_0_tmp = df_cluster_0_tmp.drop('Grupos', axis=1)
pca = PCA(componentes)
df_cluster_0_pca = pca.fit_transform(df_cluster_0_tmp)
df_cluster_0_pca = pd.DataFrame(df_cluster_0_pca, columns=['PC1', 'PC2', 'PC3'])
com = pd.DataFrame(data=pca.components_, columns=df_cluster_0_tmp.columns, index = ['PC1', 'PC2', 'PC3'])
print('PC1:\n', round(com.loc['PC1'].nlargest(10), 3))
print('\nPC2:\n', round(com.loc['PC2'].nlargest(10), 3))
print('\nPC3:\n', round(com.loc['PC3'].nlargest(10), 3))
df_cluster_0_pca.corrwith(salida_cluster_0)
Visualización de los grupos en 3D.
%matplotlib notebook
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
from IPython.display import HTML
import matplotlib.animation as animation
num_components=3
pca = PCA(num_components)
#Esta es la matriz de componentes principales
X_transformed = pca.fit_transform(df_b)
eigenvalues = pca.explained_variance_
df_c = pd.DataFrame(data=X_transformed, columns = range(num_components))
print('Varianzas:')
print(eigenvalues.round(3))
explained_variance_ratio_=pca.explained_variance_ratio_
print('\nPorcentaje de varianza de cada dimensión con respecto a la varianza total:')
print(explained_variance_ratio_.round(3))
#Se obtiene el porcentaje acumulado de varianza
print('\nPorcentaje acumulado de varianza:')
explained_variance_ratio_cumsum=explained_variance_ratio_.cumsum()
print(explained_variance_ratio_cumsum.round(3))
correl=df_c.corr()
correl=round(correl,5)
print('\nCorrelación\n', correl)
fig4 = plt.figure("K-Means Clustering 3D")
ax = fig4.add_subplot(1,1,1, projection='3d')
def init():
scatter = ax.scatter(df_c[0], df_c[1], df_c[2],
c=kmeans_pca['Grupos'], s=50)
#ax.set_title('K-Means Clustering')
ax.set_xlabel('1er Factor')
ax.set_ylabel('2do Factor')
ax.set_zlabel('3er Factor')
plt.colorbar(scatter)
plt.savefig('recursos/graficas/k-means-clustering-pca-3D-PCA.png', dpi=300)
return fig4,
def animate(i):
ax.view_init(elev=30., azim=3.6*i)
return fig4
def start():
ani = animation.FuncAnimation(fig4, animate, init_func=init,
frames=100, interval=100, blit=True)
return ani
HTML(start().to_jshtml())